`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/08/09 13:33:36
// Design Name: 
// Module Name: iclark_ipark
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module iclark_ipark(
    input                   sys_clk_i           ,
    input                   sys_rst_n_i         ,

    input                   iclark_ipark_en_i   ,
    output                  iclark_ipark_ack_o  ,

    input signed[17:0]      cordic_sin_i        ,   
    input signed[17:0]      cordic_cos_i        ,
    input signed[31:0]      Uq_i                ,
    input signed[31:0]      Ud_i                ,


    output signed[31:0]     Ua_o                ,   //没有用到,暂不实现
    output signed[31:0]     Ub_o                ,   //没有用到,暂不实现
    output signed[31:0]     Uc_o                ,   //没有用到,暂不实现
    output reg signed[31:0] Ualpha_o            ,
    output reg signed[31:0] Ubeta_o             
);





reg[5:0]    cnt;
reg         dealing;

reg signed[63:0]   a;
reg signed[63:0]   b;
reg signed[63:0]   c;
reg signed[63:0]   d;

assign iclark_ipark_ack_o = ( cnt == 'd7 ) ? 1'b1 : 1'b0;

always@( posedge sys_clk_i or negedge sys_rst_n_i ) begin
    if( sys_rst_n_i == 1'b0 )
        dealing <= 1'b0;
    else if( iclark_ipark_ack_o == 1'b1 )
        dealing <= 1'b0;
    else if( iclark_ipark_en_i == 1'b1 )
        dealing <= 1'b1;
    else
        dealing <= 1'b0;
end

always@( posedge sys_clk_i or negedge sys_rst_n_i ) begin
    if( sys_rst_n_i == 1'b0 )
        cnt <= 'd0;
    else if( dealing == 1'b1 )
        cnt <= cnt + 1'b1;
    else
        cnt <= 'd0;
end



always@( posedge sys_clk_i or negedge sys_rst_n_i ) begin
    if( sys_rst_n_i == 1'b0 ) begin
        a <= 'd0;
        b <= 'd0;   
        c <= 'd0;
        d <= 'd0;      
    end
    else if( cnt == 'd1 ) begin
        a <= Uq_i * cordic_sin_i;
        b <= Ud_i * cordic_cos_i;   
        c <= Uq_i * cordic_cos_i;
        d <= Ud_i * cordic_sin_i;
    end
    else if( cnt == 'd3) begin
        a <= a >>> 16;
        b <= b >>> 16;
        c <= c >>> 16;
        d <= d >>> 16;
    end
    else begin
        a <= a;
        b <= b;
        c <= c;
        d <= d;
    end
end

always@( posedge sys_clk_i or negedge sys_rst_n_i ) begin
    if( sys_rst_n_i == 1'b0 ) begin
        Ualpha_o <= 'd0;
        Ubeta_o <= 'd0;      
    end
    else if( cnt == 'd5 ) begin
        Ualpha_o <= b - a;
        Ubeta_o <= c + d;     
    end
    else begin
        Ualpha_o <= Ualpha_o;
        Ubeta_o <= Ubeta_o;
    end
end











// localparam  S_IDLE        =   'd0;
// localparam  S_STEP_0      =   'd1;
// localparam  S_STEP_1      =   'd2;
// localparam  S_STEP_2      =   'd3;
// localparam  S_STEP_3      =   'd4;
// localparam  S_STEP_4      =   'd5;
// localparam  S_STEP_5      =   'd6;
// localparam  S_ACK         =   'd7;

// reg                 a_mul_en;
// reg signed[31:0]    a_mul_a;
// reg signed[31:0]    a_mul_b;
// wire signed[63:0]   a_mul_out;

// reg                 b_mul_en;
// reg signed[31:0]    b_mul_a;
// reg signed[31:0]    b_mul_b;
// wire signed[63:0]   b_mul_out;

// reg                 addsub_en;
// reg                 addsub_sel;
// reg signed[63:0]    addsub_a;
// reg signed[63:0]    addsub_b;
// wire signed[64:0]   addsub_out;


// reg[4:0] state , next_state;
// reg[3:0] cnt;

// assign iclark_ipark_ack_o = ( state == S_ACK ) ? 1'b1 : 1'b0;

// assign Ua_o = 'd0;
// assign Ub_o = 'd0;
// assign Uc_o = 'd0;

// always@( posedge sys_clk_i ) begin
//     if( state == S_IDLE )
//         cnt <= 'd0;
//     else if( state != next_state )
//         cnt <= 'd0;
//     else
//         cnt <= cnt + 1'b1;
// end

// always@( posedge sys_clk_i or negedge sys_rst_n_i ) begin
//     if( sys_rst_n_i == 1'b0 )
//         state <= S_IDLE;
//     else
//         state <= next_state;
// end


// always@(*) begin
//     case (state)
//         S_IDLE: 
//             if( iclark_ipark_en_i == 1'b1 )
//                 next_state <= S_STEP_0;
//             else
//                 next_state <= S_IDLE;
//         S_STEP_0:
//             if( cnt == 'd4 )
//                 next_state <= S_STEP_1;
//             else
//                 next_state <= S_STEP_0;
//         S_STEP_1:
//             if( cnt == 'd8 )
//                 next_state <= S_STEP_2;
//             else
//                 next_state <= S_STEP_1;
//         S_STEP_2:
//             next_state <= S_STEP_3;
//         S_STEP_3:
//             if( cnt == 'd4 )
//                 next_state <= S_STEP_4;
//             else
//                 next_state <= S_STEP_3;
//         S_STEP_4:
//             if( cnt == 'd8 )
//                 next_state <= S_STEP_5;
//             else
//                 next_state <= S_STEP_4;
//         S_STEP_5:
//             next_state <= S_ACK;
//         S_ACK:
//             next_state <= S_IDLE;
//         default: next_state <= S_IDLE;
//     endcase
// end

// always@( posedge sys_clk_i or negedge sys_rst_n_i ) begin
//     if( sys_rst_n_i == 1'b0 ) begin
//         a_mul_en <= 1'b0;
//         a_mul_a  <= 'd0;
//         a_mul_b  <= 'd0;
//         b_mul_en <= 1'b0;
//         b_mul_a  <= 'd0;
//         b_mul_b  <= 'd0 ;
//     end
//     else if( state == S_STEP_0 ) begin
//         a_mul_en <= 1'b1;
//         a_mul_a <= Ud_i;
//         a_mul_b <= cordic_cos_i;
//         b_mul_en <= 1'b1;
//         b_mul_a <= Uq_i;
//         b_mul_b <= cordic_sin_i;
//     end
//     else if(state == S_STEP_3) begin
//         a_mul_en <= 1'b1;
//         a_mul_a <= Uq_i;
//         a_mul_b <= cordic_cos_i;
//         b_mul_en <= 1'b1;
//         b_mul_a <= Ud_i;
//         b_mul_b <= cordic_sin_i;
//     end
//     else begin
//         a_mul_en <= 1'b0;
//         a_mul_a <= a_mul_a;
//         a_mul_b <= a_mul_b;
//         b_mul_en <= 1'b0;
//         b_mul_a <= b_mul_a;
//         b_mul_b <= b_mul_b;
//     end
// end

// always@( posedge sys_clk_i or negedge sys_rst_n_i  ) begin
//     if( sys_rst_n_i == 1'b0 ) begin
//         addsub_en   <= 1'b0;
//         addsub_sel  <= 1'b0;
//         addsub_a    <=  'd0;
//         addsub_b    <=  'd0;
//     end
//     else if( state == S_STEP_1 ) begin
//         addsub_en   <= 1'b1;
//         addsub_sel  <= 1'b1;
//         addsub_a    <= a_mul_out;
//         addsub_b    <= b_mul_out;
//     end
//     else if( state == S_STEP_4 ) begin
//         addsub_en   <= 1'b1;
//         addsub_sel  <= 1'b0;
//         addsub_a    <= a_mul_out;
//         addsub_b    =  b_mul_out;
//     end
//     else begin
//         addsub_en   <= 1'b0;
//         addsub_sel  <= 1'b0;
//         addsub_a    <= addsub_a;
//         addsub_b    =  addsub_b;
//     end
// end


// always@( posedge sys_clk_i or negedge sys_rst_n_i )begin
//     if( sys_rst_n_i == 1'b0 )
//         Ualpha_o <= 'd0;
//     else if( state == S_STEP_2 )
//         Ualpha_o <= ( addsub_out >>> 32);
//     else
//         Ualpha_o <= Ualpha_o;
// end

// always@( posedge sys_clk_i or negedge sys_rst_n_i )begin
//     if( sys_rst_n_i == 1'b0 )
//         Ubeta_o <= 'd0;
//     else if( state == S_STEP_5 )
//         Ubeta_o <= ( addsub_out >>> 32);
//     else
//         Ubeta_o <= Ubeta_o;
// end

// assign a_mul_out = a_mul_a * a_mul_b;
// // mult_gen_32_32 mult_gen_32_32_a_hp
// // (
// //     .CLK        (       sys_clk_i       ),  
// //     .A          (       a_mul_a         ),
// //     .B          (       a_mul_b         ),  
// //     .CE         (       a_mul_en        ),
// //     .P          (       a_mul_out       )
// // );
// assign b_mul_out = b_mul_a * b_mul_b;
// // mult_gen_32_32 mult_gen_32_32_b_hp
// // (
// //     .CLK        (       sys_clk_i       ),  
// //     .A          (       b_mul_a         ),
// //     .B          (       b_mul_b         ),  
// //     .CE         (       b_mul_en        ),
// //     .P          (       b_mul_out       )
// // );

// assign addsub_out = addsub_a + addsub_b;
// // c_addsub_64 c_addsub_64_hp
// // (
// //     .A          (       addsub_a        ),
// //     .B          (       addsub_b        ),
// //     .CLK        (       sys_clk_i       ),
// //     .ADD        (       addsub_sel      ),
// //     .CE         (       addsub_en       ),
// //     .S          (       addsub_out      )
// // );

endmodule
